package com.google.sitebricks.rendering.control;

import com.google.sitebricks.Respond;

import java.util.Map;

/**
 * @author Dhanji R. Prasanna (dhanji@gmail com)
 */
class EmbeddedRespond implements Respond {
    private static final String BODY_BEGIN = "<body";
    private static final String BODY_END = "</body>";
    private static final char NOT_IN_QUOTE = '\0';

    //memo fields
    private String body;

    private final Map<String, ArgumentWidget> arguments;
    private final Respond delegate;

    public EmbeddedRespond(Map<String, ArgumentWidget> arguments, Respond respond) {
        this.arguments = arguments;
        this.delegate = respond;
    }


    public String toHeadString() {
        if (null == body) {
            //extract and store
            extract(delegate.toString());
        }

        //we discard the <head> tag rendered in the child page and
        //instead return only what was directly rendered with writeToHead()
        return delegate.getHead();
    }

    //state machine extracts <body> tag content
    private void extract(String htmlDoc) {

        //now extract the contents of <body>...
        int bodyStart = htmlDoc.indexOf(BODY_BEGIN) + BODY_BEGIN.length();

        //scan for end of the <body> start tag (beginning of body content)
        char quote = NOT_IN_QUOTE;
        for (int body = bodyStart; body < htmlDoc.length(); body++) {
            final char c = htmlDoc.charAt(body);
            if (isQuoteChar(c)) {
                if (quote == NOT_IN_QUOTE)
                    quote = c;
                else if (quote == c)
                    quote = NOT_IN_QUOTE;
            }

            if ('>' == c && NOT_IN_QUOTE == quote) {
                bodyStart = body + 1;
                break;
            }
        }

        int bodyEnd = htmlDoc.indexOf(BODY_END, bodyStart);

        //if there was no body tag, just embed whatever was rendered directly
        if (-1 == bodyEnd) {
            EmbeddedRespond.this.body = htmlDoc;
        }
        else
            EmbeddedRespond.this.body = htmlDoc.substring(bodyStart, bodyEnd);
    }



    private static boolean isQuoteChar(char c) {
        return '"' == c || '\'' == c;
    }

    public void write(String text) {
        delegate.write(text);
    }

    public HtmlTagBuilder withHtml() {
        return delegate.withHtml();
    }

    public void write(char c) {
        delegate.write(c);
    }

    public void require(String require) {
        delegate.require(require);
    }

    public void redirect(String to) {
        delegate.redirect(to);
    }

    public void writeToHead(String text) {
        delegate.writeToHead(text);
    }

    public void chew() {
        delegate.chew();
    }

    public String getRedirect() {
        return delegate.getRedirect();
    }


    public String getContentType() {
        return delegate.getContentType();
    }

    public ArgumentWidget include(String name) {
        return arguments.get(name);
    }

    public String getHead() {
        return delegate.getHead();
    }

    @Override
    public String toString() {
        if (null == body) {
            extract(super.toString());
        }

        return body;
    }

}
